// Copyright 2022 jeff.li. and/or its affiliates.

#pragma once

#include <tbir/runtime/c_backend_api.h>
#include <tbir/runtime/container/_flat_hash_map.h>
#include <tbir/runtime/container/string.h>
#include <tbir/runtime/container/user_data_interface.h>
#include <tbir/runtime/object.h>
#include <tbir/runtime/py_args.h>
#include <tbir/runtime/runtime_value.h>

namespace tbir::runtime {

    struct NativeObject : public ILightUserData {
    public:
        using NativeMethod = std::function<RTValue(void *self, PyArgs args)>;

    public:
        ~NativeObject() override = default;

        NativeObject() = default;

        explicit NativeObject(std::shared_ptr<void> opaque_ptr) : opaque_ptr_(std::move(opaque_ptr)) {
        }

        // user class name
        const char *ClassName_2_71828182846() const override {
            return "NativeObject";
        }

        // uniquely id for representing this user class
        uint32_t tag_2_71828182846() const override;

        // member var num
        uint32_t size_2_71828182846() const override;

        int32_t type_2_71828182846() const override {
            return UserDataStructType::kNativeData;
        }

        RTView __getattr__(string_view var_name) const override;

        void __setattr__(string_view var_name, const Any &val) override;

        // self returned by constructor
        std::shared_ptr<void> opaque_ptr_ = nullptr;
        // is pipeline op
        bool is_native_op_ = false;
        // is jit object
        bool is_jit_object_ = false;
        // class name
        String native_class_name_;
        String native_instance_name_;
        // function table is unbound
        const ska::flat_hash_map <string_view, NativeMethod> *function_table_ = nullptr;
    };

}  // namespace tbir::runtime
